package com.mjk.common.core.jdbc.service.plus.provider.impl.wrap;


import com.mjk.common.base.model.BaseEntity;
import com.mjk.common.core.jdbc.annotation.Id;
import com.mjk.common.core.jdbc.service.plus.provider.abstractor.AbstractSqlServerProvider;
import com.mjk.common.core.jdbc.service.plus.provider.abstractor.IWrapperProvider;
import com.mjk.common.core.jdbc.service.plus.wrap.BeeComplexQueryWrapper;
import com.mjk.common.core.jdbc.service.plus.wrap.BeeQueryWrapper;
import com.mjk.common.core.jdbc.util.TableUtils;
import com.mjk.common.core.jdbc.util.provider.InsertSqlProvider;
import com.mjk.common.core.jdbc.util.provider.SelectSqlProvider;
import com.mjk.common.core.jdbc.util.provider.SqlProvider;
import com.mjk.common.util.ObjectUtils;
import com.mjk.common.util.ReflectionUtils;
import com.mjk.common.util.StrUtils;
import org.apache.ibatis.jdbc.SQL;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class SqlServerWrapProvider extends AbstractSqlServerProvider implements IWrapperProvider {

    public String insert(Map<String, Object> map) {
        BaseEntity app = (BaseEntity) map.get("item");
        StrUtils.notNull(app, "app is null");
        String tableName = TableUtils.getTableName(app);
        return new SQL().INSERT_INTO(tableName).INTO_COLUMNS(getInsertFiled(app))
                .INTO_VALUES(getInsertFiledValue(app)).toString();
    }


    @Override
    public String selectByExample(Map<String, Object> map) {
        BeeQueryWrapper example = (BeeQueryWrapper) map.get("wrap");
        String tableName = TableUtils.getTableName(example.getInstance());
        SQL sql = new SQL();
        sql.FROM(tableName);
        if (ObjectUtils.isNotEmpty(example.toWherSql()))
            sql.WHERE(example.toWherSql());
        if (ObjectUtils.isNotEmpty(example.groupBy())) {
            sql.SELECT(SelectSqlProvider.getSelectFiledByOrder(example));
            sql.GROUP_BY(example.groupBy());
        } else {
            sql.SELECT(example.toSelect());
        }
        if (ObjectUtils.isNotEmpty(example.orderBy())) {
            sql.ORDER_BY(example.orderBy());
        }

        return sql.toString();
    }

    public static String getInsertFiled(BaseEntity t) {
        List<String> getField = new ArrayList<>();
        List<Field> fields = SqlProvider.getValidTableFiled(t, true);
        for (Field f : fields) {
            Id id = f.getAnnotation(Id.class);
            if (null != id) {
                continue;
            }
            Object o = ReflectionUtils.getFieldValue(t, f.getName());
            getField.add(SqlProvider.getCloumName(f));
        }
        return StrUtils.join(getField, ",");
    }

    public static String getInsertFiledValue(BaseEntity t) {
        List<String> sql = new ArrayList<>();
        List<Field> fields = SqlProvider.getValidTableFiled(t, true);
        for (Field f : fields) {
            Id id = f.getAnnotation(Id.class);
            if (null != id) {
                continue;
            }
            Object o = ReflectionUtils.getFieldValue(t, f.getName());
            if (ObjectUtils.isNotEmpty(o)) {
                sql.add(SqlProvider.getFiledType("#{item.", t, f));
            } else {
                sql.add("#{item." + f.getName() + ",jdbcType=VARCHAR}");
            }
        }
        return StrUtils.join(sql, ",");
    }
}
